package com.taoyun.web.controller;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.taoyun.mapper.FileMapper;
import com.taoyun.mapper.MpFileMapper;
import com.taoyun.mapper.USendFMapper;
import com.taoyun.pojo.entity.File;
import com.taoyun.pojo.entity.ObjectSize;
import com.taoyun.pojo.entity.User;
import com.taoyun.pojo.vo.RecycleFileVO;
import com.taoyun.service.IFileService;
import com.taoyun.service.IObsService;
import com.taoyun.utils.Response;
import com.taoyun.utils.UserUtil;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;

/**
 *  文件操作
 *
 * @author FengJingdong
 */
@RestController
public class FileController {

    @Autowired
    private IFileService fileService;

    @Autowired
    private IObsService obsService;

    @Autowired
    private MpFileMapper mpFileMapper;

    @Autowired
    private USendFMapper uSendFMapper;

    @Autowired
    private FileMapper fileMapper;


    /**
     *  删除文件到回收站 story编号 - PDRQ29
     *  http://localhost:8080/taoyun/v1/put-recycle-bin
     * @param request 用于获取 header 的 token （tokenLogin = XXXX）
     * @param fileIds 删除的文件id 数组
     */
    @PutMapping("taoyun/v1/put-recycle-bin")
    public Response putRecycleBin(HttpServletRequest request,
                                  @RequestParam("fileIds")List<Integer> fileIds){
        if(fileIds.size() ==0){
            return Response.error("401","传参错误，fileIds 为空");
        }
        User user = UserUtil.getUserByRequest(request);
        List<Integer> collect = fileIds.stream().filter(fileId ->
                UserUtil.hasDeletePermission(user, fileId)).collect(Collectors.toList());
        if(collect.size()==fileIds.size()){
            fileService.putRecycleBin(user.getUserId(),collect);
            return Response.setShortMsg(200,"已删除到回收站");
        }else{
            return Response.error("401","部分文件没有删除权限");
        }
    }

    /**
     *  回收站浏览 story编号 - PDRQ30
     *  http://localhost:8080/taoyun/v1/get-recycle-bin
     * @param page 第几页
     * @param size 每页分页数
     * @param request  用于获取 header 的 token （tokenLogin = XXXX）
     * @return PageInfo<RecycleFileVO> pageInfo ,
     *         (list<RecycleFileVO> fileId ,fileName，fileType，lastTime ，author)
     */
    @GetMapping("taoyun/v1/get-recycle-bin")
    public Response getRecycleBin(@RequestParam(value = "page", defaultValue = "1") Integer page,
                                  @RequestParam(value = "size",defaultValue = "5")Integer size,HttpServletRequest request){
        User user = UserUtil.getUserByRequest(request);
        PageHelper.startPage(page,size,true);
        List<RecycleFileVO> list = fileService.getRecycleBin(user.getUserId());
        PageInfo<RecycleFileVO> pageInfo = new PageInfo<>(list);
        return Response.success(pageInfo);
    }

    /**
     *
     *  回收站文件恢复（批量） story编号 - PDRQ31
     *  http://localhost:8080/taoyun/v1/restore-recycle-bin
     *  @param fileIds 删除的文件id 数组
     */
    @PutMapping("taoyun/v1/restore-recycle-bin")
    public Response restoreRecycleBin(@RequestParam("fileIds")List<Integer> fileIds){
        if(fileIds.size() ==0){
            return Response.error("401","传参错误，fileIds 为空");
        }
        String msg = fileService.restoreRecycleBin(fileIds);
        if(msg.endsWith("!")){
            return Response.error(msg);
        }else{
            return Response.setShortMsg(200,"文件已恢复");
        }
    }

    /**
     *  彻底删除文件
     *  http://localhost:8080/taoyun/v1/delete-from-recycle-bin
     * @param request 用于获取 header 的 token （tokenLogin = XXXX）
     * @param fileIds 删除的文件id 数组
     */
    @DeleteMapping("taoyun/v1/delete-from-recycle-bin")
    public Response deleteFromRecycleBin(HttpServletRequest request,
                                         @RequestParam("fileIds")List<Integer> fileIds){
        if(fileIds.size() ==0){
            return Response.error("401","传参错误，fileIds 为空");
        }
        User user = UserUtil.getUserByRequest(request);
        StringBuilder error = new StringBuilder("部分文件没有权限无法删除-fileId:");
        // 过滤文件操作权限
        List<Integer> collect = fileIds.stream().filter(fileId ->{
                    if(UserUtil.hasDeletePermission(user, fileId)){
                        return true;
                    }else {
                        error.append(" ");
                        error.append(fileId);
                        return false;
                    }
                }).collect(Collectors.toList());
        fileService.deleteFromRecycleBin(collect);
        if(collect.size()==fileIds.size()){
            return Response.setShortMsg(200,"文件已彻底删除");
        }else {
            return Response.error(error.toString());
        }
    }

    /**
     *  复制文件（单个）
     *  http://localhost:8080/taoyun/v1/copyfile
     * @param sobj 复制的文件，如果在文件夹里面（"gct/123.txt"）
     * @param dobj 粘贴的文件，如果在文件夹里面（"gct/123.txt"）
     */
    @PutMapping("taoyun/v1/copyfile")
    public Response copyfile(@Param("sobj") String sobj, @Param("dobj") String dobj,HttpServletRequest request){
        User user=UserUtil.getUserByRequest(request);
        fileService.copyObject(sobj,dobj);
        return Response.setShortMsg(201,"文件已复制");
    }

    /**
     *  移动文件（单个）
     *  http://localhost:8080/taoyun/v1/movefile
     * @param sobj 移动的文件，如果在文件夹里面（"gct/123.txt"）
     * @param dobj 移动的文件，如果在文件夹里面（"gct/123.txt"）
     */
    @PutMapping("taoyun/v1/movefile")
    public Response movefile(@Param("sobj") String sobj, @Param("dobj") String dobj,HttpServletRequest request){
        User user=UserUtil.getUserByRequest(request);
        fileService.moveObject(sobj,dobj);
        return Response.setShortMsg(202,"文件已移动");
    }

    /**
     *当前路径下模糊查询
     * http://localhost:8080/taoyun/v1/File/searchfile_byName
     * @param now_path  当前路径
     * @param file_name 文件名
     * @return  文件列表
     */
    @GetMapping("taoyun/v1/File/searchfile_byName")
    public Response SearchFile_ByName(@RequestParam(value = "page", defaultValue = "1") Integer page,
                                      @RequestParam(value = "size",defaultValue = "5")Integer size,String now_path, String file_name) {
        PageHelper.startPage(page,size,true);
        List<File> path_file = fileService.SearchFile_ByName(now_path,file_name);
        PageInfo<File> pageInfo = new PageInfo<>(path_file);
        return  Response.success(pageInfo);
    }

    /**
     * 浏览当前路径的文件
     * http://localhost:8080/taoyun/v1/File/showfile
     * @param now_path 当前路径
     * @return 文件列表
     */
    @GetMapping("taoyun/v1/File/showfile")
    public Response ShowFile(@RequestParam(value = "page", defaultValue = "1") Integer page,
                             @RequestParam(value = "size",defaultValue = "5")Integer size,String now_path) {
        PageHelper.startPage(page,size,true);
        List<File> path_file = fileService.ShowFile(now_path);
        PageInfo<File> pageInfo = new PageInfo<>(path_file);
        return  Response.success(pageInfo);
    }

    /**
     * 计算用户所用空间
     * http://localhost:8080/taoyun/v1/File/get_user_data
     * @param ObjectName  （必须）用户根文件夹的根目录名（String）
     * @return  总文件大小（long）
     *  {
     *     "code": "200",
     *     "msg": "请求成功",
     *     "data": 556
     * }
     */
    @GetMapping("taoyun/v1/File/get_user_data")
    public Response get_user_data(String ObjectName) {
        ObjectSize a = fileService.get_user_data(ObjectName);
        return Response.success(a.getUsedSize());
    }

    @GetMapping("taoyun/v1/test")
    public Response add_objectData(String ObjectName) {
        return Response.success(fileService.add_objectData(ObjectName));
    }

    /**
     * 本接口用于获取文件的链接，该链接可以直接点开
     * example：
     * http://localhost:8080/taoyun/v1/getObjectLink
     * @param expireSeconds          (必选)该链接过期时间  如果为-1则是永久分享
     * @param objectName             (必选)需要获取链接的对象名(包括路径)
     *
     * 正常结果：
     * {
     *     "code": "200",
     *     "msg": "分享链接已生成",
     *     "data": "https://taoyun.obs.cn-north-4.myhuaweicloud.com:443/777/111.txt?AccessKeyId=OUPKVVTMV5WNNQBPYBPQ&Expires=1600873089&Signature=OlIz120X8Xeg52mz5EE3llWh98Q%3D"
     * }
     *
     */
    @GetMapping("taoyun/v1/getObjectLink")
    public Response getObjectLink(@Param("expireSeconds") long expireSeconds,
                                  @Param("objectName") String objectName,
                                  HttpServletRequest request) {
        User user=UserUtil.getUserByRequest(request);
        return Response.success("分享链接已生成",fileService.getObjectLink(expireSeconds,objectName));
    }

    /**
     * 本接口用于重命名对象，也可以对文件夹进行重命名
     * example：
     * http://localhost:8080/taoyun/v1/renameObject
     * @param objectName            (必须)旧的对象名(带路径)  peng/test2/test.jpeg
     * @param newObjectName         (必须)新的对象名（带路径） peng/test2/testRename01.jpeg
     * 正常：
     * {
     *     "code": "200",
     *     "msg": "重命名成功",
     *     "data": null
     * }
     */
    @PutMapping("taoyun/v1/renameObject")
    public Response renameObject(@Param("objectName") String objectName,
                                 @Param("newObjectName") String newObjectName,
                                 HttpServletRequest request) {
        User user=UserUtil.getUserByRequest(request);

        if(fileService.renameObjects(objectName,newObjectName)){
            return Response.setShortMsg(200,"重命名成功");
        }
        else{
            return Response.error("重命名失败，请检查是否存在重名！");
        }
    }

    /**
     * 本接口用于在文件并行系统下创建桶。
     * example：
     * http://localhost:8080/taoyun/v1/createFileSystem
     * @param bucketName   (必选)需要新建的存储桶的名字
     * @return
     */
    @PostMapping("taoyun/v1/createFileSystem")
    public Response createFileSystem(@Param("bucketName") String bucketName) throws IOException {
        fileService.createFileSystem(bucketName);
        return Response.success();
    }


//    /**
//     * 本接口用于单个上传文件到obs-不再使用
//     * http://localhost:8080/taoyun/v1/upload
//     * @param file     文件对象
//     * @param file_Path     obs目标文件路径
//     * @param request       请求
//     * @return
//     * @throws IOException
//     * {
//            "code": "200",
//            "msg": "上传文件成功",
//            "data": { (对应File实体类对象信息) }
//        }
//     */
//    @PostMapping("taoyun/v1/upload")
//    public Response upload(@RequestParam("file") MultipartFile file,
//                           @RequestParam("file_path") String file_Path,
//                           HttpServletRequest request
//                           ) throws IOException{
//
//        User user = UserUtil.getUserByRequest(request);
//        String author = user.getName();
//        int user_Id = user.getUserId();
//        File fn = fileService.insertFileAndUSendF(file,file_Path,author,user_Id);
//        try {
//            //System.out.println("obs=====");
//            fileService.uploadFile(file, file_Path);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        return Response.success("上传文件成功",fn);
//    }

    /**
     * 多个文件上传
     * @param files 选择一个或多个文件
     * @param file_Path 当前路径
     * @param request 获取用户信息
     * @return  成功提示
     * @throws IOException
     *
     * http://localhost:8080/taoyun/v1/uploads
     */
    @PostMapping("taoyun/v1/uploads")
    public Response uploadFolder(@RequestParam("files") MultipartFile[] files,
                                 @RequestParam("file_path") String file_Path,
                                 HttpServletRequest request
    ) throws IOException{

        User user = UserUtil.getUserByRequest(request);
        String author = user.getName();
        int user_Id = user.getUserId();
        //System.out.println(files.length);
        for (int i = 0; i< files.length; i++) {
            fileService.judgeObjectSizeWhenUpload(files[i],file_Path);
            try {
                fileService.uploadFile(files[i], file_Path);
            } catch (Exception e) {
                e.printStackTrace();
            }
            fileService.handleUploadFile(files[i], file_Path, author, user_Id);
        }
        return Response.success("上传"+files.length+"个文件成功");
    }

    /**
     * 文件夹上传
     * @param fileFolderList 选择一个文件夹
     * @param file_Path 当前路径
     * @return  成功提示
     * @throws IOException
     *
     * http://localhost:8080/taoyun/v1/uploadFolder
     */
    @PostMapping("taoyun/v1/uploadFolder")
    public Response uploads(@RequestParam("fileFolderList") MultipartFile[] fileFolderList,
                           @RequestParam("file_path") String file_Path,
                           HttpServletRequest request
    ) throws IOException{

        User user = UserUtil.getUserByRequest(request);
        String author = user.getName();
        int user_Id = user.getUserId();
        System.out.println(fileFolderList.length);
        for (int i = 0; i< fileFolderList.length; i++) {
            fileService.judgeObjectSizeWhenUpload(fileFolderList[i],file_Path);
            try {
                fileService.uploadFile(fileFolderList[i], file_Path);
            } catch (Exception e) {
                e.printStackTrace();
            }
            fileService.handleUploadFile(fileFolderList[i], file_Path, author, user_Id);
            //添加创建空文件夹的属性条目
            fileService.insertFileNullFolder(fileFolderList[i], file_Path, author);
        }

        return Response.success("上传文件夹成功");
    }



    /**
     * 本接口用于下载文件的链接，该链接可以直接点开
     * example：
     * http://localhost:8080/taoyun/v1/downloadfile
     * @param bucketName   (必选)下载的文件所属桶的名字
     * @param objectNames   (必选)下载的对象名字
     * @param fileLocatePrefix     (必选)本地下载位置
     * 正常结果：
     * {
     *     "code": "200",
     *     "msg": "下载文件成功",
     *     "data": "null"
     * }
     *
     * @return
     */
    @GetMapping("taoyun/v1/downloadfile")
    public Response downloadfile(@Param("bucketName") String bucketName,@Param("objectNames") String objectNames,@Param("fileLocatePrefix") String fileLocatePrefix, HttpServletRequest request) throws IOException {

        User user = UserUtil.getUserByRequest(request);
        return fileService.downloadfile(bucketName,objectNames,fileLocatePrefix);

    }



    /**
     * 本接口用于显示下载文件的进度
     * example：
     * http://localhost:8080/taoyun/v1/downloadprogress
     * @param bucketName   (必选)下载的文件所属桶的名字
     * @param objectName   (必选)下载的对象名字
     * 正常结果：
     * {
     *     "code": "200",
     *     "msg": "下载文件成功",
     *     "data": "null"
     *
     *
     * @return
     */
    @GetMapping("taoyun/v1/downloadprogress")
    public Response downloadprogress(@Param("bucketName") String bucketName,@Param("objectName") String objectName) throws IOException {
        fileService.downloadprogress(bucketName,objectName);
        return Response.setShortMsg(200,"显示下载进度成功");
    }


    /**
     * 本接口用于下载文件
     * example：
     * http://localhost:8080/taoyun/v1/showobjectName
     * @param bucketName   (必选)下载的文件所属桶的名字
     * @param objectName  (必选)下载的对象名字
     * 正常结果：
     * {
     *     "code": "200",
     *     "msg": "显示文件属性成功",
     *     "data": "null"
     *
     *
     * @return
     */
    @GetMapping ("taoyun/v1/showobjectName")
    public Response showobjectName(@Param("bucketName") String bucketName,@Param("objectName") String objectName) throws IOException {
        fileService.showobjectName(bucketName,objectName);
        return Response.setShortMsg(200,"显示文件属性成功");
    }




    /**
     * 本接口用于分享文件。
     * example：
     * http://localhost:8080/taoyun/v1/shareobject
     * @param url   (必选)生成的分享url地址
     * @Param dobj   (必须)目标地址
     *
     * 正常结果：
     * {
     *     "code": "200",
     *     "msg": "接收成功",
     *     "data": null
     * }
     *
     *
     * @return
     */
    @PutMapping("taoyun/v1/shareobject")
    public Response shareobject(@org.apache.ibatis.annotations.Param("url") String url, @org.apache.ibatis.annotations.Param("dobj") String dobj,HttpServletRequest request) throws IOException{
        User user = UserUtil.getUserByRequest(request);
        fileService.shareobject(url,dobj);
        return Response.setShortMsg(200,"接收成功");
    }


    /**
     *  前端获取绝对路径测试 ---暂不可用
     * @param request
     * @param response
     * @throws Exception
     */
    @PostMapping("taoyun/v1/uploadtest2")
    private void document_a(HttpServletRequest request, HttpServletResponse response) throws Exception{
        String file_D = request.getParameter("Dem");
        System.out.println(file_D);
        //返回前端获取的地址
    }

    /**
     * 本接口用于获取下载的文件的链接(可多个，但不可以下载文件夹)
     * example：
     * http://localhost:8080/taoyun/v1/getDownloadLink
     * @param objectNames             (必选)需要获取链接的对象名(包括路径)(可以多个)
     *
     * 正常结果：
     * {
     *     "code": "200",
     *     "msg": "分享链接已生成",
     *     "data": "https://taoyun.obs.cn-north-4.myhuaweicloud.com:443/777/111.txt?AccessKeyId=OUPKVVTMV5WNNQBPYBPQ&Expires=1600873089&Signature=OlIz120X8Xeg52mz5EE3llWh98Q%3D"
     * }
     *
     */
    @GetMapping("taoyun/v1/getDownloadLink")
    public Response getObjectLink(@RequestParam("objectNames") List<String> objectNames,
                                  HttpServletRequest request) {
        User user=UserUtil.getUserByRequest(request);
        return Response.success("分享链接已生成",fileService.getDownloadLink(objectNames));
    }

}
